package com.rzico.sbl.ui.order

import android.Manifest
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
import android.os.SystemClock
import android.provider.Settings
import android.view.animation.BounceInterpolator
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.lifecycle.lifecycleScope
import com.amap.api.convertToLatLng
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.RouteSearchV2
import com.amap.api.setAnimateCamera
import com.amap.api.setCameraChangeListener
import com.amap.api.setOnRouteSearchListener
import com.fondesa.kpermissions.allGranted
import com.fondesa.kpermissions.anyPermanentlyDenied
import com.fondesa.kpermissions.extension.permissionsBuilder
import com.fondesa.kpermissions.extension.send
import com.lzy.okgo.utils.OkLogger
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityDeliverRouteBinding
import com.rzico.sbl.model.LatLngBean
import com.rzico.sbl.model.OrderData
import com.rzico.sbl.other.DeliverRouteOverlay
import com.rzico.sbl.other.showRouteDialog
import com.rzico.sbl.viewmodel.DeliverViewModel
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.doubleValue
import com.xinnuo.common.helper.intValue
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.utils.showHintDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


class DeliverRouteActivity : BaseActivity(R.layout.activity_deliver_route) {

    private val mBinding by lazy { ActivityDeliverRouteBinding.bind(getRootView()) }

    override fun getViewModel() = get<DeliverViewModel>()

    private lateinit var mLauncher: ActivityResultLauncher<Intent>

    private lateinit var mRouteSearch: RouteSearchV2

    // 起始点（定位）
    private var mStartPoint: LatLonPoint? = null

    // 根据距离排序后的坐标点
    private val mSortPoints = ArrayList<LatLngBean>()

    // 路径规划overlay集合
    private val mOverlayList = ArrayList<DeliverRouteOverlay>()

    override fun initData() {
        initTitle(title = "路径规划")

        initRouteSearch()

        mLauncher = requestForResult { initAmap() }

        requestPermission()
    }

    /**
     * 定位权限申请
     */
    private fun requestPermission() {
        permissionsBuilder(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
            .build()
            .send {
                when {
                    it.allGranted() -> initAmap()
                    it.anyPermanentlyDenied() -> showPermissionDialog()
                    else -> finishView()
                }
            }
    }

    /**
     * 权限禁止显示后提示操作
     */
    private fun showPermissionDialog() {
        showHintDialog(
            title = "提示",
            hint = "位置权限被禁止开启，请打开权限设置页面手动开启",
            sure = "去设置",
            cancel = "再想想",
            isForced = true,
            onCancel = { finishView() },
            onSure = {
                mLauncher.launch(
                    Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        .apply {
                            data = Uri.parse("package:$packageName")
                        }
                )
            }
        )
    }

    /**
     * 地图显示初始化
     */
    private fun initAmap() {
        mBinding
            .routeMap
            .map
            .apply {
                uiSettings.apply {
                    isZoomControlsEnabled = false     //缩放按钮，默认打开
                    isCompassEnabled = false          //指南针，默认不显示
                    isMyLocationButtonEnabled = false //定位按钮
                    isScaleControlsEnabled = true     //比例尺
                    isScrollGesturesEnabled = true    //滑动手势
                    isZoomGesturesEnabled = true      //缩放手势
                    isRotateGesturesEnabled = true    //旋转手势
                    isTiltGesturesEnabled = true      //倾斜手势
                    setLogoBottomMargin(-100)         //隐藏logo
                }

                mapType = AMap.MAP_TYPE_NAVI   //导航地图模式
                isTrafficEnabled = false       //实时交通状况
                showBuildings(true)            //显示3D楼块
                showMapText(true)              //显示底图文字
                showIndoorMap(true)            //设置是否显示室内地图
                isMyLocationEnabled = true     //是否触发定位并显示定位层

                // 定位图层设置
                myLocationStyle = MyLocationStyle().apply {
                    // 连续定位、但不会移动到地图中心点，并且会跟随设备移动
                    myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER)
                    strokeColor(Color.TRANSPARENT)     //设置定位蓝点精度圆圈的边框颜色
                    radiusFillColor(Color.TRANSPARENT) //设置定位蓝点精度圆圈的填充颜色
                    showMyLocation(true)               //设置是否显示定位小蓝点
                    // 设置定位蓝点的icon图标方法
                    myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location_point))
                }

                // 自定义地图
                setCustomMapStyle(
                    CustomMapStyleOptions().apply {
                        isEnable = true
                        styleData = getByteFromAssets("style.data")
                        styleExtraData = getByteFromAssets("style_extra.data")
                    }
                )

                // 设置用户定位信息监听
                setOnMyLocationChangeListener {
                    if (mStartPoint == null) getData()

                    mStartPoint = LatLonPoint(it.latitude, it.longitude)
                }

                // 地图加载完成监听
                setOnMapLoadedListener { }

                // 地图状态的监听
                setCameraChangeListener { }

                // marker点击事件监听
                setOnMarkerClickListener { true }

                // moveCamera(CameraUpdateFactory.changeTilt(60f)) //设置地图倾斜度，单位角度，范围（0,60）
                // moveCamera(CameraUpdateFactory.zoomTo(18f)) //设置地图缩放级别
                moveCamera(CameraUpdateFactory.newLatLng(LatLng(34.7466, 113.625367))) //默认显示郑州经纬度
            }
    }

    /**
     * 初始化路径规划
     */
    private fun initRouteSearch() {
        mRouteSearch = RouteSearchV2(this)
            .apply {
                setOnRouteSearchListener {
                    onRideRouteSearched { result, code ->
                        when (code) {
                            AMapException.CODE_AMAP_SUCCESS -> {
                                if (result != null && !result.paths.isNullOrEmpty()) {
                                    val ridePath = result.paths[0]

                                    DeliverRouteOverlay(
                                        baseContext,
                                        mBinding.routeMap.map,
                                        ridePath,
                                        result.startPos,
                                        result.targetPos
                                    ).apply {
                                        mOverlayList += this
                                        addToMap()
                                    }
                                } else OkLogger.e("暂无可规划路线！")
                            }
                            3000 -> showToast("规划点超出服务范围！")
                            3001 -> showToast("规划点暂无可规划路线！")
                            3002 -> showToast("由于道路原因，路线计算失败！")
                            3003 -> showToast("起点终点距离过长，路径规划失败！")
                            else -> showToast("规划点暂无适合路线！")
                        }
                    }
                }
            }
    }

    override fun initListener() {
        mBinding
            .routeTotal
            .oneClick {
                mSortPoints.notEmpty {
                    showRouteDialog(
                        orders = mList,
                        points = mSortPoints
                    )
                }
            }
    }

    /**
     * 获取配送中运单
     */
    override fun getData(index: Int, isLoading: Boolean) {
        getViewModel()
            .routeList(
                onSuccess = { list ->
                    mList.addItems(list)

                    var amount = 0
                    mList.forEach { item ->
                        item as OrderData
                        amount += item.shippingItems.sumOf { it.quantity.intValue }
                    }
                    mBinding.routeTotalHint.text =
                        "合计配送${mList.count()}个订单，共${amount}件商品"

                    if (mStartPoint != null) {
                        val items = arrayListOf<LatLngBean>()

                        mList.mapIndexedTo(items) { index, data ->
                            data as OrderData

                            LatLngBean(
                                point = LatLonPoint(
                                    data.lat.doubleValue,
                                    data.lng.doubleValue
                                ),
                                orderIndex = index,
                            )
                        }

                        // 运单排序并规划
                        mList.notEmpty {
                            lifecycleScope.launch(Dispatchers.IO) {
                                mSortPoints += getViewModel().sortPoints(mStartPoint!!, items)

                                withContext(Dispatchers.Main) {
                                    drawIcons()
                                }
                            }
                        }
                    } else showToast("获取位置信息失败，请返回重试！")
                }
            )
    }

    /**
     * 绘制Maker坐标点
     */
    private fun drawIcons() {
        mBinding
            .routeMap
            .map
            .apply {
                // 移动镜头到当前视角
                val bounds = LatLngBounds
                    .Builder()
                    .apply {
                        include(mStartPoint!!.convertToLatLng())

                        mSortPoints.forEach {
                            include(it.point.convertToLatLng())
                        }
                    }
                    .build()
                setAnimateCamera(
                    CameraUpdateFactory
                        .newLatLngBounds(bounds, 100)
                ) {
                    onFinish {
                        animateCamera(CameraUpdateFactory.changeTilt(60f))
                    }
                }

                // 添加起点marker
                addMarker(
                    MarkerOptions()
                        .icon(
                            BitmapDescriptorFactory.fromView(
                                inflate<TextView>(R.layout.layout_marker)
                                    .apply {
                                        setBackgroundResource(R.mipmap.icon_order14)
                                    }
                            )
                        )
                        .anchor(0.5f, 0.9f)
                        .position(mStartPoint!!.convertToLatLng())
                )

                // 添加客户marker
                var fromPoint = mStartPoint
                mSortPoints.forEachIndexed { index, bean ->
                    addMarker(
                        MarkerOptions()
                            .icon(
                                BitmapDescriptorFactory.fromView(
                                    inflate<TextView>(R.layout.layout_marker)
                                        .apply {
                                            text = (index + 1).toString()
                                        }
                                )
                            )
                            .snippet(bean.orderIndex.toString())
                            .anchor(0.5f, 0.9f)
                            .position(bean.point.convertToLatLng())
                    )

                    // 发起路径规划请求
                    mRouteSearch.calculateRideRouteAsyn(
                        RouteSearchV2.RideRouteQuery(
                            RouteSearchV2.FromAndTo(fromPoint, bean.point)
                        ).apply {
                            showFields = RouteSearchV2.ShowFields.POLINE
                        }
                    )

                    fromPoint = bean.point
                }
            }
    }

    /**
     * Marker点击跳动动画
     */
    @Suppress("unused")
    private fun startDropAnimation(marker: Marker, duration: Long = 1500) {
        val start = SystemClock.uptimeMillis()
        val project = mBinding.routeMap.map.projection
        val markerLatLng = marker.position
        // 将地理坐标转换成屏幕坐标
        val markerPoint = project.toScreenLocation(markerLatLng)
        // 屏幕坐标上移100px
        markerPoint.offset(0, -100)
        // 将屏幕坐标转换成地理坐标
        val startLatLng = project.fromScreenLocation(markerPoint)
        // 插值器对象
        val interpolator = BounceInterpolator()

        lifecycleScope.launch(Dispatchers.IO) {
            var elapsed = SystemClock.uptimeMillis() - start
            var t = interpolator.getInterpolation(elapsed.toFloat() / duration)

            while (t < 1.0) {
                val lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude
                val lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude

                withContext(Dispatchers.Main) {
                    marker.position = LatLng(lat, lng)
                }

                delay(16)

                elapsed = SystemClock.uptimeMillis() - start
                t = interpolator.getInterpolation(elapsed.toFloat() / duration)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mBinding.routeMap.onCreate(savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState, outPersistentState)
        // onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mBinding.routeMap.onSaveInstanceState(outState)
    }

    override fun onResume() {
        super.onResume()
        // onResume时执行mMapView.onResume ()，重新绘制加载地图
        mBinding.routeMap.onResume()
    }

    override fun onPause() {
        super.onPause()
        // onPause时执行mMapView.onPause ()，暂停地图的绘制
        mBinding.routeMap.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        // onDestroy时执行mMapView.onDestroy()，销毁地图
        mBinding.routeMap.onDestroy()
    }

}